import folium
from folium.plugins import AntPath  # 动画路径插件
import math
import random

def bd09_to_wgs84(lat, lon):
    # BD09 -> GCJ02
    x_pi = math.pi * 3000.0 / 180.0
    x = lon - 0.0065
    y = lat - 0.006
    z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_pi)
    theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_pi)
    gcj_lon = z * math.cos(theta)
    gcj_lat = z * math.sin(theta)
    
    # GCJ02 -> WGS84（近似逆向计算，误差约1-10米）
    a = 6378245.0
    ee = 0.00669342162296594323
    dlat = _transform_lat(gcj_lon - 105.0, gcj_lat - 35.0)
    dlon = _transform_lon(gcj_lon - 105.0, gcj_lat - 35.0)
    rad_lat = gcj_lat / 180.0 * math.pi
    magic = math.sin(rad_lat)
    magic = 1 - ee * magic * magic
    sqrt_magic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrt_magic) * math.pi)
    dlon = (dlon * 180.0) / (a / sqrt_magic * math.cos(rad_lat) * math.pi)
    wgs_lat = gcj_lat - dlat
    wgs_lon = gcj_lon - dlon
    return [wgs_lat, wgs_lon]

def _transform_lat(x, y):
    ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x))
    ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(y * math.pi) + 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(y / 12.0 * math.pi) + 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0
    return ret

def _transform_lon(x, y):
    ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x))
    ret += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(x * math.pi) + 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(x / 12.0 * math.pi) + 300.0 * math.sin(x / 30.0 * math.pi)) * 2.0 / 3.0
    return ret

def generate_map(coordinates_list_ori, names, map_output_path):
    # 批量转换坐标
    colors = ["blue","cyan","green","black","magenta","yellow","red"]
    colors = ["#0000FF", "#00FFFF", "#008000", "#000000", "#FF00FF", "#FFFF00", "#FF0000"]
    colors = ['darkgreen', 'orange', 'darkred', 'blue', 'purple', 'darkblue', 'green']
    random.shuffle(colors)
    colors = colors[:len(names)]
    coordinates_list = []
    for coordinates_ori in coordinates_list_ori:
        coordinates = [bd09_to_wgs84(lat, lon) for lat, lon in coordinates_ori]
        coordinates_list.append(coordinates)

    # 创建地图对象（自动适配坐标范围）
    m = folium.Map(location=coordinates_list[0][-1], zoom_start=5)

    ii = 0
    # 3. 添加路径节点标记   
    for coordinates, name, color in zip(coordinates_list, names, colors):

        # 创建单独的地图对象（自动适配坐标范围）
        m_one = folium.Map(location=coordinates_list[0][-1], zoom_start=5)

        # 绘制路径（支持多种样式）
        # 基础路径
        folium.PolyLine(
            locations=coordinates,
            color=color,        
            weight=5,               # 线宽
            opacity=0.8,            # 透明度
            popup=name
        ).add_to(m)

        folium.PolyLine(
            locations=coordinates,
            color=color,        
            weight=5,               # 线宽
            opacity=0.8,            # 透明度
            popup=name
        ).add_to(m_one)  

        folium.Marker(
            location=[coordinates[0][0], coordinates[0][1]],
            popup=name,
            icon=folium.Icon(
                icon='circle',      # 圆形标记
                color=color,   
                fill=True,
                fill_opacity=0.7,
                html='<div style="font-size: 20px; color: %s;">%s</div>' %(color, name),
            )
        ).add_to(m)
        text_html = '''
            <div style="
                font-size: 20px;
                color: %s;
                white-space: pre-line;     /* 允许自动换行 */
                width: 200px;">
                %s<br>%s<br>%s
            </div>
        '''%(color, name[:5], name[5:11], name[11:])
        folium.map.Marker(
            [coordinates[0][0]+0.01, coordinates[0][1]],
            icon=folium.DivIcon(
                #icon_size=(200, 60),      # 宽度和高度根据文字内容调整
                icon_anchor=(0,0),
                html=text_html
            )
        ).add_to(m)        

        folium.Marker(
            location=[coordinates[0][0], coordinates[0][1]],
            popup=name,
            icon=folium.Icon(
                icon='circle',      # 圆形标记
                color=color,    
                fill=True,
                fill_opacity=0.7
            )
        ).add_to(m_one)        

        folium.Marker(
            location=[coordinates[-1][0], coordinates[-1][1]],
            popup=name,
            icon=folium.Icon(
                icon='circle',      # 圆形标记
                color='red',    
                fill=True,
                fill_opacity=0.7
            )
        ).add_to(m_one)    

        text_html = '''
            <div style="
                font-size: 20px;
                color: %s;
                white-space: pre-line;     /* 允许自动换行 */
                width: 200px;">
                %s<br>%s<br>%s
            </div>
        '''%(color, name[:5], name[5:11], name[11:])
        folium.map.Marker(
            [coordinates[0][0]+0.01, coordinates[0][1]],
            icon=folium.DivIcon(
                #icon_size=(200, 60),      # 宽度和高度根据文字内容调整
                icon_anchor=(0,0),
                html=text_html
            )
        ).add_to(m_one)          

        text_html = '''
                <div style="
                    font-size: 20px;
                    color: %s;
                    white-space: pre-line;     /* 允许自动换行 */
                    width: 200px;">
                    %s
                </div>
            '''%('red', "救灾点（沙磁科技园）")
        folium.map.Marker(
                [coordinates_list[-1][-1][0]+0.01, coordinates_list[-1][-1][1]],
                icon=folium.DivIcon(
                    #icon_size=(200, 60),      # 宽度和高度根据文字内容调整
                    icon_anchor=(0,0),
                    html=text_html
                )
            ).add_to(m_one)               

        print (name, ":", color)

        m_one.fit_bounds(m_one.get_bounds()) 
        m_one.save(map_output_path + "_" + str(ii) + ".html")
        ii += 1

        # # 动画路径（需安装antpath插件）
        # AntPath(
        #     locations=coordinates,
        #     color=color,
        #     weight=5,
        #     opacity=0.5
        # ).add_to(m)

    folium.Marker(
            location=[coordinates_list[-1][-1][0], coordinates_list[-1][-1][1]],
            popup=name,
            icon=folium.Icon(
                icon='circle',      # 圆形标记
                color='red',    
                fill=True,
                fill_opacity=0.7
            )
        ).add_to(m)   
    text_html = '''
            <div style="
                font-size: 20px;
                color: %s;
                white-space: pre-line;     /* 允许自动换行 */
                width: 200px;">
                %s
            </div>
        '''%('red', "救灾点（沙磁科技园）")
    folium.map.Marker(
            [coordinates_list[-1][-1][0]+0.01, coordinates_list[-1][-1][1]],
            icon=folium.DivIcon(
                #icon_size=(200, 60),      # 宽度和高度根据文字内容调整
                icon_anchor=(0,0),
                html=text_html
            )
        ).add_to(m)           

    # 自动调整地图视野
    m.fit_bounds(m.get_bounds())

    # 保存地图（支持离线查看）
    m.save(map_output_path + ".html")